package org.zjx.window.operation;

import java.awt.*;
import java.util.Objects;

/**
 * 窗口操作接口 - 统一的操作定义
 * 使用函数式接口定义各种窗口操作，支持操作组合和链式调用
 *
 * @author zjx
 * @since 1.0
 */
@FunctionalInterface
public interface WindowOperation {

    /**
     * 执行操作
     *
     * @param executor 操作执行器，不能为null
     * @throws IllegalArgumentException 如果executor为null
     * @throws IllegalStateException 如果执行过程中发生错误
     */
    void execute(OperationExecutor executor);

    // ========== 鼠标操作快捷方法 ==========

    /**
     * 在指定屏幕坐标点击鼠标（左键）
     *
     * @param x 屏幕X坐标
     * @param y 屏幕Y坐标
     * @return 点击操作实例
     */
    static WindowOperation click(int x, int y) {
        return executor -> executor.click(x, y);
    }

    /**
     * 在当前鼠标位置点击指定按钮
     *
     * @param button 鼠标按钮：1-左键, 2-中键, 3-右键
     * @return 点击操作实例
     * @throws IllegalArgumentException 如果button不是1,2,3
     */
    static WindowOperation click(int button) {
        validateMouseButton(button);
        return executor -> executor.click(button);
    }

    /**
     * 按下鼠标按钮
     *
     * @param button 鼠标按钮：1-左键, 2-中键, 3-右键
     * @return 按下鼠标操作实例
     * @throws IllegalArgumentException 如果button不是1,2,3
     */
    static WindowOperation pressMouse(int button) {
        validateMouseButton(button);
        return executor -> executor.pressMouse(button);
    }

    /**
     * 释放鼠标按钮
     *
     * @param button 鼠标按钮：1-左键, 2-中键, 3-右键
     * @return 释放鼠标操作实例
     * @throws IllegalArgumentException 如果button不是1,2,3
     */
    static WindowOperation releaseMouse(int button) {
        validateMouseButton(button);
        return executor -> executor.releaseMouse(button);
    }

    /**
     * 移动鼠标到屏幕绝对坐标
     *
     * @param x 屏幕X坐标
     * @param y 屏幕Y坐标
     * @return 移动操作实例
     */
    static WindowOperation move(int x, int y) {
        return executor -> executor.move(x, y);
    }

    /**
     * 移动鼠标到窗口相对坐标
     *
     * @param x 窗口内相对X坐标
     * @param y 窗口内相对Y坐标
     * @return 游戏内移动操作实例
     */
    static WindowOperation gameMove(int x, int y) {
        return executor -> executor.gameMove(x, y);
    }

    /**
     * 在窗口相对区域内随机移动鼠标
     *
     * @param rectangle 窗口内的相对区域
     * @return 随机移动操作实例
     * @throws IllegalArgumentException 如果rectangle为null
     */
    static WindowOperation gameMove(Rectangle rectangle) {
        Objects.requireNonNull(rectangle, "移动区域不能为null");
        return executor -> executor.gameMove(rectangle);
    }

    /**
     * 拖拽鼠标从起点到终点
     *
     * @param fromX 起点屏幕X坐标
     * @param fromY 起点屏幕Y坐标
     * @param toX 终点屏幕X坐标
     * @param toY 终点屏幕Y坐标
     * @return 拖拽操作实例
     */
    static WindowOperation drag(int fromX, int fromY, int toX, int toY) {
        return executor -> executor.drag(fromX, fromY, toX, toY);
    }

    // ========== 键盘操作快捷方法 ==========

    /**
     * 输入文本
     *
     * @param text 要输入的文本
     * @return 输入文本操作实例
     * @throws IllegalArgumentException 如果text为null
     */
    static WindowOperation type(String text) {
        Objects.requireNonNull(text, "输入文本不能为null");
        return executor -> executor.input(text);
    }

    /**
     * 按下并释放指定键码
     *
     * @param keyCode 键盘键码
     * @return 按键操作实例
     */
    static WindowOperation press(int keyCode) {
        return executor -> executor.press(keyCode);
    }

    /**
     * 执行快捷键组合
     *
     * @param keyCodes 键盘键码序列
     * @return 快捷键操作实例
     * @throws IllegalArgumentException 如果keyCodes为null或空数组
     */
    static WindowOperation hotkey(int... keyCodes) {
        if (keyCodes == null || keyCodes.length == 0) {
            throw new IllegalArgumentException("快捷键键码序列不能为空");
        }
        return executor -> executor.hotkey(keyCodes);
    }

    // ========== 工具操作快捷方法 ==========

    /**
     * 延迟指定毫秒数
     *
     * @param milliseconds 要延迟的毫秒数
     * @return 延迟操作实例
     * @throws IllegalArgumentException 如果milliseconds为负数
     */
    static WindowOperation delay(long milliseconds) {
        if (milliseconds < 0) {
            throw new IllegalArgumentException("延迟时间不能为负数: " + milliseconds);
        }
        return executor -> executor.delay(milliseconds);
    }

    // ========== 操作组合方法 ==========

    /**
     * 顺序执行多个操作
     *
     * @param operations 要执行的操作序列
     * @return 组合操作实例
     * @throws IllegalArgumentException 如果operations为null或包含null元素
     */
    static WindowOperation sequence(WindowOperation... operations) {
        Objects.requireNonNull(operations, "操作序列不能为null");

        for (WindowOperation op : operations) {
            Objects.requireNonNull(op, "操作序列中包含null元素");
        }

        return executor -> {
            for (WindowOperation op : operations) {
                op.execute(executor);
            }
        };
    }

    /**
     * 重复执行操作指定次数
     *
     * @param operation 要重复执行的操作
     * @param times 重复次数
     * @return 重复操作实例
     * @throws IllegalArgumentException 如果operation为null或times小于1
     */
    static WindowOperation repeat(WindowOperation operation, int times) {
        Objects.requireNonNull(operation, "要重复的操作不能为null");
        if (times < 1) {
            throw new IllegalArgumentException("重复次数必须大于0: " + times);
        }

        return executor -> {
            for (int i = 0; i < times; i++) {
                operation.execute(executor);
            }
        };
    }

    /**
     * 条件执行操作
     *
     * @param condition 条件检查操作，返回true时执行action
     * @param action 要执行的操作
     * @return 条件操作实例
     * @throws IllegalArgumentException 如果condition或action为null
     */
    static WindowOperation conditional(Condition condition, WindowOperation action) {
        Objects.requireNonNull(condition, "条件检查操作不能为null");
        Objects.requireNonNull(action, "要执行的操作不能为null");

        return executor -> {
            if (condition.test(executor)) {
                action.execute(executor);
            }
        };
    }

    /**
     * 组合多个操作（链式调用支持）
     *
     * @param next 下一个要组合的操作
     * @return 组合后的操作实例
     * @throws IllegalArgumentException 如果next为null
     */
    default WindowOperation andThen(WindowOperation next) {
        Objects.requireNonNull(next, "下一个操作不能为null");
        return executor -> {
            this.execute(executor);
            next.execute(executor);
        };
    }

    // ========== 条件接口 ==========

    /**
     * 条件检查接口
     * 用于条件执行操作
     */
    @FunctionalInterface
    interface Condition {
        /**
         * 测试条件是否满足
         *
         * @param executor 操作执行器
         * @return 如果条件满足返回true，否则返回false
         */
        boolean test(OperationExecutor executor);
    }

    // ========== 私有验证方法 ==========

    /**
     * 验证鼠标按钮参数
     *
     * @param button 鼠标按钮代码
     * @throws IllegalArgumentException 如果按钮代码无效
     */
    static void validateMouseButton(int button) {
        if (button < 1 || button > 3) {
            throw new IllegalArgumentException("无效的鼠标按钮: " + button + "，有效值为1(左键),2(中键),3(右键)");
        }
    }
}